<?php

namespace App\Service\VendorClient\Shopshqingpu;

use App\Service\Code\Normal;
use App\Service\BaseService;
use Service\AppService\IdService;
use App\Service\TaskServer\TaskWorker;
use App\Model\PssModel\ServiceConfig;
use Hyperf\Utils\Coroutine;
use Hyperf\Utils\WaitGroup;

/**
 * 上海青浦wms供应商SDK
 * @author hj
 */
class ShopshqingpuApiClient extends BaseService {
    //供应商编号
    const SUPPLIER_CODE = 'shopshqingpu';

    //配置文件
    private $config = [];

    public function __construct($apiBody = []) {
        $this->config = $apiBody;
    }

    /**
     * 创建订单
     * @param array $params
     * @return array
     */
    public function createOrder($param = []) {
        if (empty($param['supplierOrder']) || empty($param['orderGoods']) || empty($param['order']) || empty($param['binfo'])) {
            return Normal::returnCode(Normal::FAIL, "except param supplierOrder or orderGoods or order or binfo");
        }
        $orderInfo = $param['supplierOrder'];
        $goodsList = $param['orderGoods'];
        $order     = $param['order'];
        $binfo     = $param['binfo'];
        $order_sn  = $orderInfo['supplier_dsn'];
        //支付流水号
        $pay_sn = $order['paySerial'] ?? $orderInfo['pay_sn'];
        //订单时间
        $order_time = $orderInfo['cd'] ? date('Y-m-d H:i:s', $orderInfo['cd']) : date('Y-m-d H:i:s', time());
        //支付时间
        $pay_time = isset($order['payTime']) && !empty($order['payTime']) ? date('Y-m-d H:i:s', $order['payTime']) : date('Y-m-d H:i:s', time());
        //运费
        $deliver_money = $orderInfo['deliver_money'];
        //下单支付的时候支付信息
        $apply_extends = @json_decode($orderInfo['apply_extends'], true);
        //判断支付方式是否存在
        $payCommanyCode = $apply_extends['payCommanyCode'] ?? '';
        $payCommanyCode = $order['payCommanyCode'] ?? $payCommanyCode;
        $payWayInfo     = ServiceConfig::instance()->getConfigByEventsValue(self::SUPPLIER_CODE, ServiceConfig::TYPE_PAY, $payCommanyCode, false);
        if (empty($payWayInfo)) {
            return Normal::returnCode(Normal::FAIL, "支付公司编码：【{$payCommanyCode}】未映射，请联系管理员处理");
        }
        //获取下单商品信息
        $goodsNameArr        = [];
        $palceOrderGoods     = [];
        $goods_all_money     = '0.00';
        $singleGoodsSumMoney = '0.00';
        $sumTaxMoney         = '0.00';
        foreach ($goodsList as $key => $item) {
            //卖价
            $price = $item['price'];
            //商品购买规格数量
            $spec_num = $item['spec_num'];
            //商品购买数量(下单数量 X 起售数量)
            $quantity = $item['quantity'];
            //实际购买数量
            $buyAcount = $spec_num * $quantity;
            //商品税率
            $tax      = $item['tax_rate'];
            $tax_rate = bcadd((string)$tax, '1.0000', 4);
            //商品+税费
            $shipping_fee        = $key == 0 ? $deliver_money : 0;
            $single_shipping_fee = bcdiv((string)$shipping_fee, (string)$quantity, 3);
            $single_shipping_fee = ceil((float)$single_shipping_fee * 100) / 100;
            $price               = bcadd((string)$price, (string)$single_shipping_fee, 2);
            //商品包邮含税总金额
            $goodsMoney = bcmul((string)$price, (string)$quantity, 2);
            //获取商品不含税价格 ,小数第三位收了之后再进行合计计算
            $goods_price = bcdiv((string)$goodsMoney, (string)$tax_rate, 3);
            $goods_price = bcdiv((string)$goods_price, (string)$buyAcount, 3);
            //包邮不含税单价
            $singleGoodsPrice = ceil((float)$goods_price * 100) / 100;
            //包邮不含税总金额
            $singleGoodsSummaryMoney = bcmul((string)$singleGoodsPrice, (string)$buyAcount, 2);
            //税金
            $summaryTaxAmt     = bcsub((string)$goodsMoney, (string)$singleGoodsSummaryMoney, 2);
            $summaryGoodsMoney = bcadd((string)$summaryTaxAmt, (string)$singleGoodsSummaryMoney, 2);
            //金额差异 放在优惠金额
            $sub_goods_money = bcsub((string)$goodsMoney, (string)$summaryGoodsMoney, 2);
            //单个商品总金额
            $goods_all_money = bcadd((string)$goods_all_money, $goodsMoney, 2);
            //包邮不含税总金额 总和
            $singleGoodsSumMoney = bcadd((string)$singleGoodsSumMoney, $singleGoodsSummaryMoney, 2);
            //税金 总合
            $sumTaxMoney = bcadd((string)$sumTaxMoney, $summaryTaxAmt, 2);
            //下单商品组  商品单价*商品购买数量+商品运费+商品关税+商品消费税+商品增值税-计税折扣-不计税折扣
            $goodsInfo         = [
                'sku_id'          => $item['supplier_skucode'],//电商商品编号
                'qty'             => (int)$buyAcount,//数量
                'cargoUnitPrice'  => $singleGoodsPrice,//单项购买商品单价 不含税
                'cargoTotalPrice' => $singleGoodsSummaryMoney,//单项购买商品总价 等于单价乘以数量 不含税
                'cargoTotalTax'   => $summaryTaxAmt,// 单项购买商品缴税总价 同一编号商品总数备案价格对应的税金额
            ];
            $palceOrderGoods[] = $goodsInfo;
            array_push($goodsNameArr, $item['goods_name']);
        }
        $real_total_money = $orderInfo['real_total_money'];
        $bc_sub_money     = bcsub((string)$goods_all_money, (string)$real_total_money, 2);
        //如果计算有差异
        $otherPrice   = $bc_sub_money > 0 ? $bc_sub_money : '0.00';
        $requestParam = [
            'company_code'           => $order['enterpriseNum'] ?? $apply_extends['enterpriseNum'],//平台企业编码
            'company_name'           => $order['enterpriseName'] ?? $apply_extends['enterpriseName'],//平台企业名称
            'order_id'               => $order_sn,//订单号
            'order_create_time'      => $order_time,//下单时间
            'pay_time'               => $pay_time,//支付时间
            'transport_service_code' => $this->config['transportCode'],//物流供应商代号
            'receiver_province'      => $orderInfo['province'],//收件省份
            'receiver_city'          => $orderInfo['city'],//收件城市
            'receiver_county'        => $orderInfo['district'],//收件区域
            'receiver_address'       => $orderInfo['receive_address'],//收件地址
            'receiver_name'          => $orderInfo['receive_name'],//收件人
            'receiver_mobile'        => $orderInfo['recveive_phone'],//收件人电话
            'logistic_condition'     => '0',//送达类型  0表示普通 1 次日达
            'senderName'             => $this->config['senderName'],//发件人姓名 ??
            'senderTel'              => $this->config['senderTel'],//发件人电话 ??
            'senderCompanyName'      => $this->config['senderCompanyName'],//发件方公司名称 ??
            'senderAddr'             => $this->config['senderAddr'],//发件人地址 ??
            'senderCity'             => $this->config['senderCity'],//发件地城市 ??
            'senderProvince'         => $this->config['senderProvince'],//发件地省/州名 ??
            'senderCountry'          => $this->config['senderCountry'],//发件地国家 ??
            'cargoDescript'          => implode(' ', $goodsNameArr),//订单商品信息简述
            'allCargoTotalPrice'     => $singleGoodsSumMoney,//商品价格 商品集合中每个单项商品CargoTotalPrice 的合计值)
            'allCargoTotalTax'       => $sumTaxMoney,//代扣税款 商品集合中每个单项商品CargoTotalTax 的合计值
            'expressPrice'           => '0.00',//运费
            'otherPrice'             => $otherPrice,//使用积分、虚拟货币、代金券等非现金支付金额(正值)，无则填写
            'serverType'             => $this->config['serverType'],// 业务类型  S01：一般进口；S02：保税区进口
            'custCode'               => $this->config['custCode'],//海关关区代码 ??
            'operationCode'          => $this->config['operationCode'],//操作编码 1 新增，2 修改 ??
            'customDeclCo'           => $this->config['customDeclCo'],//物流进境申报企业
            'payMethod'              => (string)$payWayInfo['service_third_value'],//支付方式
            'payMerchantName'        => $payWayInfo['service_name'],//企业支付名称
            'payMerchantCode'        => $payCommanyCode,//企业支付编号
            'payAmount'              => $orderInfo['real_total_money'],//支付总金额
            'payID'                  => $order['paySerial'] ?? $apply_extends['paySerial'],//支付交易号
            'payTime'                => date('YmdHis', strtotime($pay_time)),//支付交易时间
            'neutral_package'        => '0',//包装类型 0 贴标包装，1 中性包装，2 指定包装，3 特殊订单，4 其他
            'insuredFee'             => '0.00',//保价费 商品保险费用, 保留 5位小数,无则填 0
            'buyerRegNo'             => $orderInfo['buyer_phone'],//订购人的交易平台注册号
            'customerName'           => $orderInfo['buyer_realname'],//订购人姓名
            'customerIdType'         => '1',//订购人证件类别 默认1
            'customerId'             => $orderInfo['buyer_idcard'],//订购人证件号
            'customerTel'            => $orderInfo['buyer_phone'],//订购人电话
            'assureCode'             => $this->config['assureCode'],//担保扣税的企业海关注册登记编号 ??
            'emsNo'                  => $this->config['emsNo'],//账册编号
            'note'                   => $orderInfo['order_remark'] ?: '',//备注
            'version'                => $this->config['version'],//网关版本
            'order_items'            => $palceOrderGoods
        ];
        $data         = [
            'method' => 'createOrder',
            'data'   => json_encode($requestParam, JSON_UNESCAPED_UNICODE),
        ];
        return $this->execute($data);
    }

    /**
     * 获取取消订单
     */
    public function cancelOrder($params = []) {
        $data = [
            'method' => 'cancelOrder',
            'data'   => [
                'order_id' => $params['supplierOrder']['supplier_dsn'],
            ],
        ];
        return $this->execute($data);
    }

    /**
     * 签名
     * @param $data
     * @return string
     */
    public function sign($data) {
        $str = $data . $this->config['appKey'];
        return strtoupper(md5($str));
    }

    /**
     * 毫秒
     */
    public static function msectime() {
        list($msec, $sec) = explode(' ', microtime());
        return (float)sprintf('%.0f', (floatval($msec) + floatval($sec)) * 1000);
    }

    /**
     * CURL请求
     * @param $params
     * @return array
     */
    public function execute($param = []) {
        $method = $param['method'];
        $data   = $param['data'];
        if (!isset($this->config[$method])) {
            return Normal::returnCode(Normal::FAIL, "请求路由未设置");
        }
        // if (empty($param['data'])) {
        //     return Normal::returnCode(Normal::FAIL, "数据不能为空");
        // }
        $url = $this->config['baseUrl'];
        if (empty($url)) {
            return Normal::returnCode(Normal::FAIL, "接口地址不能为空");
        }
        $pushData  = [
            'sign'        => $this->sign($data),
            'notify_type' => $this->config[$method],
            'notify_id'   => (string)(strtolower(self::msectime() . uniqid(rand(100000, 999999)))),
            'notify_time' => date('Y-m-d H:i:s'),
            'wms_id'      => $this->config['wms_id'],
            'stock_id'    => $this->config['stock_id'],
            'owner_id'    => $this->config['owner_id'],
            'platform_id' => '',
            'data'        => $data,
        ];
        $parameter = [
            [
                'tag'    => self::SUPPLIER_CODE . '_' . $method,
                'uid'    => IdService::instance()->getOtherID(),
                'url'    => $url,
                'data'   => $pushData,
                'method' => 'post',
                'format' => 'json',
                'header' => [
                    "Content-Type: application/json",
                ],
            ],
        ];
        $resTask   = TaskWorker::instance()->addTask($parameter);
        $resTask   = current($resTask);
        $result    = @json_decode($resTask['response']['result'], true);
        if (isset($result['success']) && $result['success'] === true) {
            return Normal::returnCode(Normal::SUC, "请求成功", $result);
        } else {
            $msg = $result['error_msg'] ?? '请求失败';
            return Normal::returnCode(Normal::FAIL, $msg);
        }
    }


}